有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

rest MapStruct Java流

您好,我对streams等非常陌生,只是出于培训目的,我正在尝试使用mapstruct构建简单的api。 我的问题是,我真的不知道如何返回转换后的父值以及该实体中的转换字段

这是我的简单目标

public class RecipeDTO {


    private Integer id;

    private String title;

    private String description;

    private String imgUrl;

    private String directions;

    private String prepTime;

    private Integer servings;

    private String category;

    private Set<IngredientDTO> ingredientDTOSet = new HashSet<>();
}

实体

public class Recipe {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "recipe_id")
    private Integer id;

    @NotNull
    @Column(name = "recipe_title")
    private String title;

    @NotNull
    @Column(name = "recipe_description")
    private String description;

    @Column(name = "recipe_img_url")
    private String imgUrl;

    @NotNull
    @Column(name = "recipe_direction")
    private String directions;

    @NotNull
    @Column(name = "prep_time")
    private String prepTime;

    @NotNull
    @Column(name = "servings")
    private Integer servings;

    @NotNull
    @Column(name = "category")
    private String category;

    @OneToMany(mappedBy = "recipe",
            cascade = CascadeType.ALL)
    private Set<Ingredient> ingredients = new HashSet<>();

}

服务(仅一种方法)

@Override
    public List<RecipeDTO> findAll() {

        log.debug("\n" + this.getClass().getSimpleName() + " -> findAll() \n");

        return recipeRepository.findAll()
                .stream()
                .map(recipe -> RecipeMapper.INSTANCE.recipeToRecipeDTO(recipe))
                .collect(Collectors.toList());
    }


@Mapper(componentModel = "spring", uses = {IngredientMapper.class})
public interface RecipeMapper {

    RecipeMapper INSTANCE = Mappers.getMapper(RecipeMapper.class);

    @Mappings({
            @Mapping(source = "ingredients", target = "ingredientDTOSet")
    })
    RecipeDTO recipeToRecipeDTO(Recipe recipe);


}

如何转换嵌套bean? 当我试图获取所有食谱时,抛出异常

爪哇。lang.NullPointerException:null 在com。马特乌斯兹格博斯基。爸爸。应用程序编程接口。制图员。RecipeMapperImpl。ingredientSetToIngredientDTOSet(RecipeMapperImpl.java:52)~[classes/:na] 在com。马特乌斯兹格博斯基。爸爸。应用程序编程接口。制图员。RecipeMapperImpl。recipeToRecipeDTO(RecipeMapperImpl.java:32)~[classes/:na] 在com。马特乌斯兹格博斯基。爸爸。服务RecipeServiceImpl。lambda$findAll$0(RecipeServiceImpl.java:38)~[classes/:na] 在爪哇。util。流动参考管道$3$1。接受(ReferencePipeline.java:193)~[na:1.8.0\u 181] 在爪哇。util。ArrayList$ArrayListSpliterator。foreachreserving(ArrayList.java:1382)~[na:1.8.0_181] 在爪哇。util。流动抽象管道。copyInto(AbstractPipeline.java:481)~[na:1.8.0_181] 等等

看起来是有配料的,但当我在做食谱时,并不是所有的东西都是好的


共 (3) 个答案

  1. # 1 楼答案

    这不是关于java流的问题。Java流api正在调用recipeToRecipeDTO方法,该方法失败。理想情况下,方法recipeToRecipeDTO应该能够将整个配方对象转换为RecipeDTO

    要解决此问题,需要在RecipeMapper中添加一个方法,将一个Ingredient实体对象转换为IngredientDTO

  2. # 2 楼答案

    您可以使用流的映射功能

    List<Recipe> list = ... //however you get your original list
    List<RecipeDTO> dtos = list.stream().map(mapper::convert).collect(Collectors.toList);
    

    我假设您的mapstruct方法名为“convert”,映射器的变量名为“mapper”


    列表的映射将为流中的每个条目调用给定的方法(mapper::convert),然后流将包含该方法所有调用的所有返回值。因此,在您的情况下:它将转换列表中的每个条目,然后列表将包含所有转换的元素

    之后,您只需要再次收集流,这样您就又有了一个列表


    编辑后,此答案不再有效,因为您已更改了问题并使用了我的答案

    关于你的后续问题: 一般来说,要转换嵌套bean:只要嵌套bean的结构相同,mapstruct就会立即进行转换。如果存在差异,则必须对其进行注释。如果没有看到代码的这一部分,我无法告诉您Ingrediant和IngRediantTo之间的区别

    您可以尝试查看生成的类,并查看导致NullPointerException的行。那么你有胶水有什么区别。然后将其注释到mapper界面

    一般来说,对于嵌套bean: 1) 您可以在映射器中添加接口方法“ingredientToIngredientDTO”。并在该方法的右侧注释差异(如果需要)。MapStruct将它用于RecipeToripedTo方法! 2) 您可以注释嵌套的差异。例如@Mapping(source=“components.nameA”,target=“ingrediendtoset.nameB”)

    但你现在提出的问题与开始时完全不同,要回答这个问题,我需要更多的信息。因此,我更愿意将其重新编辑为原始问题。如果我的提示还不够,可以问一个有足够信息的新的

  3. # 3 楼答案

    问题是您将componentModel = "spring"Mappers工厂混合在一起。当您使用spring组件模型时,所使用的映射器将自动连接到生成的类中,Mappers工厂仅初始化实例。这意味着您的配方映射器没有被注入

    为了解决这个问题,您应该在任何地方使用默认的componentModel,或者使用spring并注入映射器

    另外,您现在进行映射的方式并不是真正的性能。您只需向映射器添加一个映射列表的方法,并调用该方法,而不用使用流